package com.history.app;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.GroupLayout.ParallelGroup;
import javax.swing.GroupLayout.SequentialGroup;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.LayoutStyle;
import javax.swing.WindowConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

import com.history.business.ArticleManager;
import com.history.common.Logit;
import com.history.common.RandomHelper;
import com.history.common.SpringContextFactory;
import com.history.common.file.FileProcess;
import com.history.domain.bean.Article;

public class TextAreaDemo extends JFrame implements DocumentListener {
	private static Logit log = Logit.getInstance(SwingDragDrop.class);
	
	private static TextAreaDemo textAreaDemo;
	public static TextAreaDemo getInstance() {
		if (textAreaDemo == null) {
			textAreaDemo = new TextAreaDemo();
		}
		return textAreaDemo;
	}
	
	String articleId;
	private JLabel 		jLabel1;
	private JScrollPane jScrollPane1;
	private JScrollPane jScrollPane2;
	private JTextArea 	textTitle;
	private JTextArea 	textArea;
	private JButton 	btnSubmit;
	private JButton 	btnClose;

	private static final String COMMIT_ACTION = "commit";

	private static enum Mode {
		INSERT, COMPLETION
	};

	private Mode mode = Mode.INSERT;

	private TextAreaDemo() {
		super("TextAreaDemo");
		initComponents();
		
		textTitle.getDocument().addDocumentListener(this);
		textArea.getDocument().addDocumentListener(this);

		InputMap im1 = textTitle.getInputMap();
		ActionMap am1 = textTitle.getActionMap();
		im1.put(KeyStroke.getKeyStroke("ENTER"), COMMIT_ACTION);
		am1.put(COMMIT_ACTION, new CommitAction());		
		
		InputMap im2 = textArea.getInputMap();
		ActionMap am2 = textArea.getActionMap();
		im2.put(KeyStroke.getKeyStroke("ENTER"), COMMIT_ACTION);
		am2.put(COMMIT_ACTION, new CommitAction());

	}

	private void initComponents() {
		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		
		jLabel1 = new JLabel("Spectacular...");
		
		textTitle = new JTextArea();
		textTitle.setColumns(20);
		textTitle.setLineWrap(true);
		textTitle.setRows(2);
		textTitle.setWrapStyleWord(true);
		
		textArea = new JTextArea();
		textArea.setColumns(20);
		textArea.setLineWrap(true);
		textArea.setRows(5);
		textArea.setWrapStyleWord(true);

		jScrollPane1 = new JScrollPane(textTitle);
		jScrollPane2 = new JScrollPane(textArea);

		btnClose  = new JButton("Close..");
		btnSubmit = new JButton("Update");
		btnSubmit.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
            	System.out.println("submit!");
              	Article article = new Article();
            	article.setId(articleId);
            	article.setTitle(textTitle.getText());
            	article.setContent(textArea.getText());
            	
            	// Init local manager
            	ArticleManager articleManagerLocal = SpringContextFactory.getArticleManager(false);
            	ArticleManager articleManager 	   = SpringContextFactory.getArticleManager(true);
            	try {
            		// Update article into Local database
					String key = RandomHelper.generateRandomKey();
					article.setSysKey(key);
            		articleManagerLocal.updateArticle(article);

					try {
						// Update article into Server database
	            		articleManager.updateArticle(article);
					} catch (Exception e) {
						JOptionPane.showMessageDialog(null, "Network has problem! This article will be synchronize to server later");
						// If the network is disconnected or has trouble.
						// save article id and action into text files
						String line = article.getId() +","+ key;						
						FileProcess.write(line);
					}
				} catch (Exception e) {
					log.error(e.getMessage(), e);					
				}
				
            	JOptionPane.showMessageDialog(null, "Update article successfully!");
            	getInstance().showArticle(false);
            }
		});
		btnClose.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {            			
            	getInstance().showArticle(false);
            }
		});
		
		
		GroupLayout layout = new GroupLayout(getContentPane());
		getContentPane().setLayout(layout);

		// Create a parallel group for the horizontal axis
		ParallelGroup hGroup = layout
				.createParallelGroup(GroupLayout.Alignment.LEADING);
		// Create a sequential and a parallel groups
		SequentialGroup h1 = layout.createSequentialGroup();
		ParallelGroup h2 = layout
				.createParallelGroup(GroupLayout.Alignment.TRAILING);
		// Add a scroll panel and a label to the parallel group h2
		h2.addComponent(jScrollPane1, GroupLayout.Alignment.LEADING,
				GroupLayout.DEFAULT_SIZE, 500, Short.MAX_VALUE);
		h2.addComponent(jScrollPane2, GroupLayout.Alignment.LEADING,
				GroupLayout.DEFAULT_SIZE, 500, Short.MAX_VALUE);
		h2.addComponent(jLabel1, GroupLayout.Alignment.LEADING,
				GroupLayout.DEFAULT_SIZE, 500, Short.MAX_VALUE);
		h2.addComponent(btnSubmit, GroupLayout.Alignment.LEADING,
				GroupLayout.DEFAULT_SIZE, 20, 40);
		h2.addComponent(btnClose, GroupLayout.Alignment.LEADING,
				GroupLayout.DEFAULT_SIZE, 20, 40);

		// Add a container gap to the sequential group h1
		h1.addContainerGap();
		// Add the group h2 to the group h1
		h1.addGroup(h2);
		h1.addContainerGap();

		// Add the group h1 to hGroup
		hGroup.addGroup(Alignment.TRAILING, h1);
		// Create the horizontal group
		layout.setHorizontalGroup(hGroup);

		// Create a parallel group for the vertical axis
		ParallelGroup vGroup = layout
				.createParallelGroup(GroupLayout.Alignment.LEADING);
		// Create a sequential group
		SequentialGroup v1 = layout.createSequentialGroup();
		// Add a container gap to the sequential group v1
		v1.addContainerGap();
		// Add a label to the sequential group v1
		v1.addComponent(jLabel1);
		v1.addComponent(btnSubmit);
		v1.addComponent(btnClose);
		v1.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED);
		// Add scroll panel to the sequential group v1
		v1.addComponent(jScrollPane1, GroupLayout.DEFAULT_SIZE, 50,
				Short.MAX_VALUE);
		v1.addComponent(jScrollPane2, GroupLayout.DEFAULT_SIZE, 300,
				Short.MAX_VALUE);
		v1.addContainerGap();

		// Add the group v1 to vGroup
		vGroup.addGroup(v1);
		// Create the vertical group
		layout.setVerticalGroup(vGroup);
		pack();

	}

	// Listener methods

	public void changedUpdate(DocumentEvent ev) {
	}

	public void removeUpdate(DocumentEvent ev) {
	}

	private class CommitAction extends AbstractAction {
		public void actionPerformed(ActionEvent ev) {
			if (mode == Mode.COMPLETION) {
				int pos1 = textTitle.getSelectionEnd();
				textTitle.insert(" ", pos1);
				textTitle.setCaretPosition(pos1 + 1);
				
				int pos2 = textArea.getSelectionEnd();
				textArea.insert(" ", pos2);
				textArea.setCaretPosition(pos2 + 1);

				mode = Mode.INSERT;
			} else {
				textTitle.replaceSelection("\n");
				textArea.replaceSelection("\n");
			}
		}
	}

	@Override
	public void insertUpdate(DocumentEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void setArticle(String id) {
		articleId = id;
		//Get article
		ArticleManager articleManager = SpringContextFactory.getArticleManager(false);
		Article article = null;
		try {
			article = articleManager.findById(id);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			log.error(e1.getMessage(), e1);
		}

		if (article != null) {
			setTitle(article.getTitle());
			setContent(article.getContent());
		}
	}

	public void setTitle(String title) {
		textTitle.setText(title);
	}
	
	public void setContent(String content) {
		textArea.setText(content);
	}
	
	public void showArticle(boolean flag) {
		getInstance().setVisible(flag);
	}
	
}